package ar.edu.itba.it.cg.grupo01.game.action.score;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import ar.edu.itba.it.cg.grupo01.game.GameMode;
import ar.edu.itba.it.cg.grupo01.utils.Utils;

public class Scores implements Serializable, Iterable<Score> {

	private static final long serialVersionUID = 1L;

	private List<Score> scores;
	private static final String scorePath = "properties/scores/";
	private URL path;

	private Scores(URL path) {
		this.path = path;
		this.scores = new ArrayList<Score>();
	}

	public static Scores load(String circuitName, GameMode gameMode) {

		URL path = getScorePath(circuitName, gameMode);

		Scores scores = new Scores(path);
		try {
			ObjectInputStream highscores = new ObjectInputStream(
					new FileInputStream(path.getFile()));
			scores = (Scores) highscores.readObject();
		} catch (FileNotFoundException e) {
		} catch (IOException e) {
		} catch (ClassNotFoundException e) {
		}

		return scores;
	}

	private static final URL getScorePath(String circuitName, GameMode gameMode) {
		return Utils.getResourceURL(gameMode.getScore(scorePath, circuitName));
	}

	public Score save() {

		Score highScore = null;
		try {
			highScore = getHighScore();
			highScore = (highScore == null ? null : (Score) highScore.clone());
		} catch (CloneNotSupportedException e1) {
			// Will never happen
		}

		try {
			ObjectOutputStream highscores = new ObjectOutputStream(
					new FileOutputStream(path.getFile()));
			highscores.writeObject(this);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return highScore;
	}

	public void addScore(Score score) {

		scores.add(score);

		Collections.sort(scores);

		int newSize = scores.size() < 5 ? scores.size() : 5;

		this.scores = new ArrayList<Score>(this.scores.subList(0, newSize));

	}

	public Score getScore(int position) {
		return this.scores.get(position);
	}

	public Iterator<Score> iterator() {
		return scores.iterator();
	}

	public Score getHighScore() {
		return scores.isEmpty() ? null : scores.get(0);
	}

    public boolean isEmpty() {
        return scores.isEmpty();
    }

}
